var Yosemin = {};

function confirmDeletion() {
    return window.confirm(i18n.deleteConfirmQuestion);
}

function selectManyCheckboxesClick(container, event) {
    if (! event) var event = window.event;
    var target = getEventTarget(event);
    if (target.tagName != 'LABEL' && target.tagName != 'INPUT') {
		return;
	}
	if ($(container).hasClass('selectOneRadio')) {
		$(container).find('label').each(function() {
			$(this).removeClass('selected');
		});
	}
    var label = $(target).closest('label').get(0);
    if (label) {
        var checkbox = label.firstChild;
        if (! checkbox.checked) {
            label.className = '';
        }
        else {
            label.className = 'selected';
        }
    }
}

function getEventTarget(event) {
    var target = null;
    if (event.target) {
        target = event.target;
    }
    else if (event.srcElement) {
        target = event.srcElement;
    }
    return target;
}

function orderList(tableName, orderBy, order) {
    if (! order) {
        order = 'ASC';
    }
    var url = null;
    if (document.location.href.indexOf('?') != -1) {
        url = document.location.href.substring(document.location.href.indexOf('?'));
        url = url.replace(/[?&]orderName=.*&order=(ASC|DESC)/, '');
        if (! url) {
            url = '?' + url;
        }
        else if (url.substring(0, 1) != '?') {
            url = '?' + url;
        }
        if (url != '?' && ! url.match(/.*&$/)) {
            url += '&';
        }
    }
    else {
        url = '?';
    }
    url += 'orderName=' + tableName + '&orderBy=' + orderBy + '&order=' + order;
    document.location.href = url;
}

var dialogLoaded = null;

/**
 * Opens dialog with form support.
 * TODO rewrite this fragile complicated code using Yosemin.Ajax.partialPageUpdate();
 */
function Dialog(url, selectFieldId, reloadOnSuccess) {
    this.dialogBlock = $('<div class="popup"></div>').hide().appendTo('body');
    this.loaded = false;
    this.data = null;

    var loadDialog = function() {
        $.get(url, 'requestType=popup', writeDialog, 'html');
    };

    /**
     * Warning: this function is not called in this Dialog context, because
     * it is called as AJAX callback from this.loadDialog().
     */
    var writeDialog = function(data, textStatus) {
        dialogLoaded.data = data;
        dialogLoaded.dialogBlock.html(data);
        dialogLoaded.loaded = true;
        dialogLoaded.makeAjaxForm();
        dialogLoaded.open();
        focusFirstField(dialogLoaded.dialogBlock);
    };

    this.open = function() {
        if (! this.loaded) {
            dialogLoaded = this;
            loadDialog();
            return;
        }

        var titleElement = $('.popupTitle', this.dialogBlock);
        var title = titleElement.html();
        
        // TODO: clear all field values
        this.dialogBlock.jhDialog({
                modal: true,
                width: 720,
                position: 'center',
                title: title
            });
    };

    this.close = function() {
        dialogLoaded = null;
        this.dialogBlock.dialog('close');
        this.dialogBlock.html('');
    };

    this.makeAjaxForm = function() {
        var dialogForm = $('form', this.dialogBlock);
        var actionName = dialogForm.attr('action');
        dialogForm.submit(function() {
            var data = dialogForm.serialize();
            $.ajax({
                type: 'POST',
                url: actionName,
                data: data,
                success: function(data, textStatus) {
                    var ajaxResponse = new Object();
                    if (data.indexOf('<?xml ') === 0) {
                    	Yosemin.Ajax.processResponseXml(data);
                    }
                    else {
	                    eval(data);
	
	                    if (ajaxResponse.redirect) {
	                        document.location.href = ajaxResponse.redirect;
	                        return;
	                    }
	                    if (ajaxResponse.errorMsgs) {
	                        dialogLoaded.displayMessages(ajaxResponse.errorMsgs, 'error');
	                        return;
	                    }
	
	                    if (! ajaxResponse.success) {
	                        alert('AJAX: Unknown error');
	                        return;
	                    }
	
	                    if (ajaxResponse.infoMsgs) {
	                        dialogLoaded.displayMessages(ajaxResponse.infoMsgs, 'info');
	                    }
	
	                    if (selectFieldId !== undefined && selectFieldId) {
	                        var selectField = document.getElementById(selectFieldId);
	
	                        if (selectField.tagName == 'SELECT') {
	
	                        }
	                        else {
	                            // Select many field - create a label, then a checkbox with a text.
	                            var newLabelElement = document.createElement('label');
	                            newLabelElement.className = 'selected';
	                            var fieldName = $('#' + selectFieldId + '>label>option:first-child').name;
	                            var checkbox = document.createElement('input');
	                            checkbox.type = "checkbox";
	                            checkbox.name = fieldName;
	                            checkbox.value = ajaxResponse.createdObject.id;
	                            checkbox.checked = true;
	                            var text = ajaxResponse.createdObject.code;
	                            if (ajaxResponse.createdObject.name) {
	                                text = ajaxResponse.createdObject.name + ' (' + ajaxResponse.createdObject.code + ')';
	                            }
	                            var checkboxText = document.createTextNode(text);
	                            newLabelElement.appendChild(checkbox);
	                            newLabelElement.appendChild(checkboxText);
	                            selectField.appendChild(newLabelElement);
	
	                            // Scroll down to the newly inserted checkbox
	                            selectField.scrollTop = selectField.scrollHeight - selectField.clientHeight;
	                        }
	                    }
                    }

                    if (reloadOnSuccess !== undefined && reloadOnSuccess) {
                        document.location.reload();
                    }
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    alert('Request error: ' + textStatus + '\n' + errorThrown);
                }
            });
            return false;
        });
    };

    this.displayMessages = function(messages, type) {
        var html = '<ul class="' + type + 'Messages">';
        for (i in messages) {
            html += '<li>' + messages[i] + '</li>';
        }
        $('.messages', this.dialogBlock).html(html).slideDown();
    };
}

/**
 * Submits a wizard form. It is meant to be bound to th 'next' wizard button.
 * There are two types of the form - one that should be submited with the next
 * button a one that has its own submit button (eg. when creating categories).
 */
function submitWizardForm() {
    var form = document.getElementById('wizardForm');
    if (! form) {
        form = $('#contentBlock > form').get(0);
        if (form) {
            var submitButtons = $(form).find('button[type="submit"]');
            if (submitButtons.size() > 0) {
                form = $('#wizardButtonsBlock form').get(0);
            }
        }
        else {
            form = $('#wizardButtonsBlock form').get(0);
        }
    }
    if (form) {
        form.submit();
    }
    else {
        alert('ERROR: form not found.');
    }
}

function checkOrUncheckAllInRow(rowElement) {
    var checkBoxes = $('input[type="checkbox"]', rowElement);
    var checkedBoxes = $('input[type="checkbox"]:checked', rowElement);
    var turnToChecked = true;
    if (checkBoxes.size() == checkedBoxes.size()) {
        turnToChecked = false;
    }
    checkBoxes.each(function(i) {
        this.checked = turnToChecked;
    });
}

/**
 * Used in seminarWizard to toggle one form row depending on a selected value in the previous row.
 */
function toggleNextRow(comboBox, valueWhenDisplayed) {
    var rowToToggle = $(comboBox).closest('tr').next();
    if (comboBox.value == valueWhenDisplayed) {
        rowToToggle.fadeIn();
    }
    else {
        // rowToToggle.get(0).style.display = 'none';
        rowToToggle.fadeOut();
    }
}

function toggleDiscountBlock(blockId, checkbox) {
    var block = $('#' + blockId);
    if (checkbox.checked) {
        block.fadeIn();
    }
    else {
        block.fadeOut();
    }
}

function toggleMessages(toggler) {
    if (toggler.className == 'messagesRollerUp') {
        $(toggler.parentNode).find('ul').slideUp();
        toggler.className = 'messagesRollerDown';
    }
    else {
        $(toggler.parentNode).find('ul').slideDown();
        toggler.className = 'messagesRollerUp';
    }
}

function toggleKarmayogaTypes(row) {
    if ($(row).find(':checked').size() > 0) {
        $('#karmayogaBlock').fadeIn();
    }
    else {
        $('#karmayogaBlock').fadeOut();
    }
}

function submitFormToUrl(comboBox, url) {
    var formToSubmit = $(comboBox).closest('form').get(0);
    formToSubmit.action = url;
    formToSubmit.submit();
    return false;
}

function viPaymentTypeChanged(comboBox) {
    if (comboBox.value == 'bank') {
        $('#paymentInfo-cash').slideUp();
        $('#paymentInfo-bank').slideDown();
    }
    else if (comboBox.value == 'cash') {
        $('#paymentInfo-bank').slideUp();
        $('#paymentInfo-cash').slideDown();
    }
    else {
        $('#paymentInfo-bank').slideUp();
        $('#paymentInfo-cash').slideUp();
    }
}

function toggleBySliding(element) {
    if (element) {
        element.slideToggle();
    }
    return false;
}

function openInDialog(elementId, title) {
    $('#' + elementId).dialog({
            modal: true,
            width: 660,
            title: title
        });
}

function showPaymentDatails(radio) {
    var options = $(radio).closest('ul').find('input');
    options.each(
        function() {
            if (this != radio) {
                $(this.parentNode.nextSibling).slideUp();
            }
        }
    );
    $(radio.parentNode.nextSibling).slideDown();
}

/**
 * Used on payment choice step of registration wizard. If a user selects payment type before selecting
 * the organization, select the organization by JavaScript.
 */
function selectOrganization(paymentTypeRadio) {
    $organizationRadio = $(paymentTypeRadio).closest('ul').closest('li').children('label').find('input');
    if ($organizationRadio.size() > 0) {
        $organizationRadio.get(0).checked = true;
    }
}

function toggleBlockByHeader(header, propertyKey, blockId) {
    var img = header.firstChild;
    var propertyValue;
    if (img.src.match(/.*toggle-plus\.png/)) {
        img.src = img.src.replace('toggle-plus', 'toggle-minus');
        propertyValue = 1;
    }
    else {
        img.src = img.src.replace('toggle-minus', 'toggle-plus');
        propertyValue = 0;
    }
    var block = $(header.parentNode.nextSibling);
    if (blockId) {
        block = $('#' + blockId);
    }
    block.toggle();

    // Save the property
    $.post(config.sessionPropertySetUrl, {key: propertyKey, value: propertyValue});
}

function focusFirstField(relativeTo) {
    if (relativeTo == undefined) {
        relativeTo = document;
    }
    var elem = $('input:visible', relativeTo).get(0);
    var select = $('select:visible', relativeTo).get(0);
    if (select && elem) {
        if (select.offsetTop < elem.offsetTop) {
            // elem = select;
        }
    }
    if (! elem) {
    	elem = select;
    }
    var textarea = $('textarea:visible', relativeTo).get(0);
    if (textarea && elem) {
        if (textarea.offsetTop < elem.offsetTop) {
            // elem = textarea;
        }
    }
    if (! elem) {
    	elem = textarea;
    }
    if (elem) {
        elem.focus();
    }
}

function closePopup(element) {
    var uiDialog = $(element).closest('.ui-dialog');
    var closeAnchor = $('.ui-dialog-titlebar-close', uiDialog);
    closeAnchor.click();
}

function disableButton(button) {
    // $(button).attr('disabled','disabled');
}

/**
 * Tries to convert all non-ASCII characters to their closest ASCII siblings.
 * Returns a string in lower case.
 */
function toLowerCaseAsciiText(text) {
    text = text.toLowerCase();
    var sDiak   = "áäčćđďéěíĺľłňóôöŕřšťúůüýž";
    var bezDiak = "aaccddeeilllnooorrstuuuyz";
    var tx = "";
    for (var p = 0; p < text.length; p++) {
        if (sDiak.indexOf(text.charAt(p)) != -1) {
            tx += bezDiak.charAt(sDiak.indexOf(text.charAt(p)));
        }
        else tx += text.charAt(p);
    }
    return tx;
}

function suggestLogin(field, suggestLoginUrl) {
    if (! document.getElementById('login').value) {
        var data = {
            'first_name' : document.getElementById('first_name').value,
            'last_name' : document.getElementById('last_name').value,
            'email' : document.getElementById('email').value
        };
        // var data = formToSubmit.serialize();
        $.ajax({
            type: 'GET',
            url: suggestLoginUrl,
            data: data,
            success: function(data, textStatus) {
                var suggestedLogin = data;
                var loginField = document.getElementById('login');
                if (! loginField.value) {
                    loginField.value = suggestedLogin;
                }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                // be quiet
            }
        });
    }
}

function setProtocolType(form, securedConnectionInfo) {
    if (document.getElementById('securedConnection').value == sql.trueValue) {
        if (document.cookie && document.cookie.indexOf('securedConnection=') == -1) {
            alert(securedConnectionInfo);
        }
        if (form.action.match(/^http:.*/)) {
            // Action is a fully qualified URL
            form.action = form.action.replace(/^http:(.*)/, 'https:$1');
        }
        else if (form.action.match(/^https:.*/)) {
            // Action is already in HTTPS
        }
        else {
            // Action does not contain protocol and server name
            form.action = 'https://' + document.domain + form.action;
        }
    }
    else {
        if (form.action.match(/^http:.*/)) {
            // Action is already in HTTPS
        }
        else if (form.action.match(/^https:.*/)) {
            // Action is a fully qualified URL
            form.action = form.action.replace(/^https:(.*)/, 'http:$1');
        }
        else {
            // Action does not contain protocol and server name
            form.action = 'http://' + document.domain + form.action;
        }
    }
}

$(window).load(function() {
	
	$( document ).tooltip({
		items: ".hasTooltip",
		content: function() {
			return $(this.parentNode).find('.tooltip').html();
		}
	});
});

function initJQueryUiWidgets() {
    // $('button').button();
}

/*
$(document).ready(function() {
    initJQueryUiWidgets();
});

$('body').ajaxComplete(function() {
    initJQueryUiWidgets();
});
*/

/** Toggler for registration wizard / payment type step. */
function togglePaymentPlace(radioButton) {
    if (radioButton.checked) {
        $(radioButton.parentNode.nextSibling).slideDown();
        $(radioButton).closest('li').siblings().each(function () {
            $(this).children('label+div'). slideUp(); // css('display', 'none');
        });
    }
}

function showPaymentTypesOfOrganization(organizationComboBox) {
    var orgId = organizationComboBox.value;
    $('.organizationPaymentOptions').each(function() {
        $(this).find('.paymentTypeDetails').hide();
        $(this).hide();
    });
    $('input[name="payment_type"]').each(function() {
        this.checked = false;
    });
    if (orgId) {
        $('#organization_' + orgId).slideDown();
        // If there is only one payment option for the selected organization, select it.
        var $paymentTypeRadioButtons = $('#organization_' + orgId).find(':radio');
        if ($paymentTypeRadioButtons.size() == 1) {
        	$paymentTypeRadioButtons.get(0).checked = true;
        }
    }
}

Yosemin.Ajax = {
		
	/**
	 * Generic AJAX page update function.
	 * Expects XML response conforming to JSF schema:
	 * http://java.sun.com/xml/ns/javaee/web-partialresponse_2_0.xsd
	 * Usually, the response contains "update" elements with id attributes a CDATA content.
	 * Value of the id attribute matches the id of an HTML element which should be updated
	 * by the CDATA content.
	 */
	partialPageUpdate: function(url, formElement, extraParams, successCallback) {
		var data = null;
		if (formElement) {
			if (! url) {
				url = $(formElement).attr('action');
			}
			data = $(formElement).serialize();
		}
		if (extraParams) {
			if (data) {
				data += '&';
			}
			else {
				data = '';
			}
			data += jQuery.param(extraParams);
		}
		
		jQuery.ajax({
			type: 'POST',
			'url': url,
			dataType: 'xml',
			'data': data,
			success: function(data, status, ajaxRequest) {
				Yosemin.Ajax.processResponseXml(ajaxRequest.responseText);
				if (successCallback) {
					successCallback(data, status, ajaxRequest);
				}
			},
			error: function(jqXHR, textStatus, errorThrown) {
			},
			complete: function(jqXHR, textStatus) {
			}
		});
	},

	processResponseXml: function(responseXml) {
		var xmlDoc = jQuery.parseXML(responseXml);
		var updateNodeList = xmlDoc.getElementsByTagName('update');
		for (var i = 0; i < updateNodeList.length; i++) {
			var updateNode = updateNodeList[i];
			var id = updateNode.getAttribute('id');
			var elementToUpdate = document.getElementById(id);
			if (elementToUpdate) {
				jQuery(elementToUpdate).html(updateNode.childNodes[0].data);
			}
			else {
				log("Error updating the page: Element with ID '" + id + "' does not exist.");
			}
		}
		var redirect = xmlDoc.getElementsByTagName('redirect');
		if (redirect.length > 0) {
			document.location.href = redirect.item(0).getAttribute('url');
			return;
		}
	}
};

Yosemin.Popup = {

	/**
	 * Opens read only popup dialog. Used for "show more info about something" functionality. 
	 */
	open: function(url, event) {
		if (! event) var event = window.event;
		
	    var serchDialogHTML = null;
	    // Create the popup body and set its max height to 90% of the document height (JQuery's maxHeight does not work).
	    var divHtml = '<div class="popup" style="max-height:' + ($(document).height() * 0.9) + 'px"></div>';
	    var dialogBlock = $(divHtml).hide().appendTo('body');
	
	    var openWithContent = function($content) {
	        serchDialogHTML = $content;
	        dialogBlock.html($content);
	        var titleElement = $('.popupTitle', dialogBlock);
	        var title = titleElement.html();
	        // TODO: clear all field values
	        dialogBlock.jhDialog({
	            modal: true,
	            width: 720,
	            position: 'center',
	            title: title
	        });
	    };
	
        if (event.ctrlKey || event.shiftKey) {
            event.preventDefault();
            document.location.href = url;
            return false;
        }
        if (serchDialogHTML) {
            openWithContent(serchDialogHTML);
        }
        else {
            $.ajax({
                type: "POST",
                url: url,
                data: 'requestType=popup',
                success: openWithContent
            });
        }
        return false;
	}
};


/**
 * Logs the message. In debug mode, show alert, since the console log message is easy to overlook.
 */
function log($message) {
	if (debugMode) {
		alert($message);
	}
	else {
		if (typeof console == "undefined") {
			var console = {log: function() {}};
		}
		console.log($message);
	}
}

/**
 * Taken from http://stackoverflow.com/questions/5172454/remove-hide-tables-empty-columns-including-th
 */
function removeEmptyColumns(tableId) {
	jQuery('#' + tableId + ' th').each(function(i) {
		var tds = $(this).parents('table').find('tr td:nth-child(' + (i + 1) + ')');
		var isEmpty = true;
		tds.each(function(j) { if (this.tagName == 'TD' && $.trim(this.innerHTML)) isEmpty = false; });
		
		if (isEmpty) {
			$(this).hide();
			tds.hide();
		}
	});
}

/** https://developers.google.com/recaptcha/docs/customization */
var RecaptchaOptions = {
	theme : 'white'
};

/**
 * Function used for autocomplete functionality. When the form is submited,
 * a corresponding ID (key) of the autocompleted value must be found and set
 * in a special hidden field.
 */
Yosemin.Autocomplete = {
	create: function(textFieldId, visibleOptions, valueFieldId, labelValueMap) {
		$(document.getElementById(textFieldId)).autocomplete({
			'source': visibleOptions,
			autoFocus: true
		});
	},
	
	showAllItemsLabel: 'Show All Items',
	valueDidNotMatchMessage: "Value '{0}' didn't match any item"
};

/**
 * JavaScript taken from http://jqueryui.com/autocomplete/#combobox
 * Creates an autocomplete field from a combo box.
 * Text value must match one of the combo box values.
 * It has a button for showing all options.
 *//*
(function( $ ) {
	$.widget( "ui.combobox", {
		options: {
		},
		
		_create: function() {
			var input,
				that = this,
				wasOpen = false,
				select = this.element.hide(),
				selected = select.children( ":selected" ),
				value = selected.val() ? selected.text() : "",
				wrapper = this.wrapper = $( "<span>" )
					.addClass( "ui-combobox" )
					.insertAfter( select );

			function removeIfInvalid( element ) {
				var value = $( element ).val(),
					matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( value ) + "$", "i" ),
					valid = false;
				select.children( "option" ).each(function() {
					if ( $( this ).text().match( matcher ) ) {
						this.selected = valid = true;
						return false;
					}
				});

				if ( !valid ) {
					// remove invalid value, as it didn't match anything
					$( element )
						.val( "" )
						.attr( "title", Yosemin.Autocomplete.valueDidNotMatchMessage.replace('{0}', value))
						.tooltip( "open" );
					select.val( "" );
					setTimeout(function() {
						input.tooltip( "close" ).attr( "title", "" );
					}, 2500 );
					input.data( "ui-autocomplete" ).term = "";
				}
			}

			input = $( "<input>" )
				.appendTo( wrapper )
				.val( value )
				.attr( "title", "" )
				.addClass( "ui-combobox-input" ) // ui-state-default
				.autocomplete({
					delay: 0,
					autoFocus: true,
					minLength: 0,
					source: function( request, response ) {
						var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
						response( select.children( "option" ).map(function() {
							var text = $( this ).text();
							if ( this.value && ( !request.term || matcher.test(text) ) )
								return {
									label: text.replace(
										new RegExp(
											"(?![^&;]+;)(?!<[^<>]*)(" +
											$.ui.autocomplete.escapeRegex(request.term) +
											")(?![^<>]*>)(?![^&;]+;)", "gi"
										), "<strong>$1</strong>" ),
									value: text,
									option: this
								};
						}) );
					},
					select: function( event, ui ) {
						ui.item.option.selected = true;
						that._trigger( "selected", event, {
							item: ui.item.option
						});
					},
					change: function( event, ui ) {
						if ( !ui.item ) {
							removeIfInvalid( this );
						}
					}
				});
				// .addClass( "ui-widget ui-widget-content ui-corner-left" );

			input.data( "ui-autocomplete" )._renderItem = function( ul, item ) {
				return $( "<li>" )
					.append( "<a>" + item.label + "</a>" )
					.appendTo( ul );
			};

			$('<a>')
				.attr('tabIndex', -1 )
				.attr('title', Yosemin.Autocomplete.showAllItemsLabel )
				.tooltip()
				.appendTo( wrapper )
				.button({
					icons: {
						primary: "ui-icon-triangle-1-s"
					},
					text: false
				})
				.removeClass( "ui-corner-all" )
				.addClass( "ui-combobox-toggle" ) // ui-corner-right
				.mousedown(function() {
					wasOpen = input.autocomplete( "widget" ).is( ":visible" );
				})
				.click(function() {
					input.focus();

					// close if already visible
					if ( wasOpen ) {
						return;
					}

					// pass empty string as value to search for, displaying all results
					input.autocomplete( "search", "" );
				});

			input.tooltip({
				tooltipClass: "ui-state-highlight"
			});
		},

		_destroy: function() {
			this.wrapper.remove();
			this.element.show();
		}
	});
})( jQuery );*/

/**
 * Custom dialog. Enables to have HTML in dialog title.
 */
(function ($, undefined) {
    //Run jQuery's widget factory to create the widget
    $.widget('jh.jhDialog', $.Widget, {
    	
    	options: {
    		close: function(event, ui) {
            	$(this).dialog('destroy').remove();
    		},
    		autoopen: true
    	},
    	
    	_create: function() {
    	    // Your code before calling the overridden method.
    		// this._super();
    		var title = this.options.title;
    		this.options.title = null;
    		this.element.dialog(this.options).dialog('open');
    		var dialogTitleElement = this.element.closest('.ui-dialog').find('.ui-dialog-title');
    		dialogTitleElement.html(title);
    		// $.ui.dialog.prototype._create.apply(this);
    	    // $.ui.dialog.prototype._create.call(this);
    	    // Your code after calling the overridden method.
    	},
    });
} (jQuery));

function focusFieldInDialogOpenByAjax($fieldId) {
	$(document).ready(function() {
		// Focus is not set if you don't use the timeout.
		setTimeout(function() { document.getElementById($fieldId).focus(); }, 1);
	});
}
